package com.gitee.sparta.core.cluster.strategy;

import com.gitee.sparta.core.bean.cluster.ClusterCmd;
import com.gitee.sparta.core.cluster.AbstractClusterFollower;
import com.gitee.sparta.core.cluster.balance.LoadBalance;
import com.gitee.sparta.core.property.SpartaCoreProperties;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 *      策略工厂
 * </p>
 *
 * @author zyred
 * @since v 0.0.2
 */
@Slf4j
public class StrategyFactory {

    private static final Map<Byte, Strategy> STRATEGY_CACHE = new ConcurrentHashMap<>(16);


    public static void init (RedissonClient client, LoadBalance loadBalance,
                             SpartaCoreProperties properties, AbstractClusterFollower follower) {
        STRATEGY_CACHE.put(ClusterCmd.CHANNEL_ACCEPT, new LeaderAcceptStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.ACCEPT_RESPONSE, new FollowerAcceptedStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.NEXT_FOLLOWER, new NextFollowerStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.FOLLOWER_ERROR, new FollowerErrorStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.INTERCEPTOR, new InterceptorCarryStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.CONSUME_QUEUE_DATA, new ConsumeQueueStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.FOLLOWER_RECOVER, new FollowerRecoverStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.FOLLOWER_SHUTDOWN, new FollowerShutdownStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.CONSUME_BROADCAST_DATA, new ConsumeBroadcastStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.ASK_LEADER, new AskLeaderStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.HEARTBEAT, new HeartbeatStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.SWITCHOVER_LEADER, new SwitchoverLeaderStrategy(client, loadBalance, properties, follower));
        STRATEGY_CACHE.put(ClusterCmd.PING, new FollowerPingStrategy(client, loadBalance, properties));
        STRATEGY_CACHE.put(ClusterCmd.PONG, new LeaderPongStrategy(client, loadBalance, properties));
    }

    public static Strategy getStrategy(byte command) {
        return STRATEGY_CACHE.get(command);
    }
}
